package com.ocm.pay.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ocm.core.log.exception.ServiceException;
import com.ocm.core.tool.api.ResultCode;
import com.ocm.pay.constant.ExchangeTypeConstant;
import com.ocm.pay.constant.PayTypeConstant;
import com.ocm.pay.entity.PayList;
import com.ocm.pay.entity.ShopPayinfo;
import com.ocm.pay.entity.UserPayinfo;
import com.ocm.pay.service.IPayListService;
import com.ocm.pay.service.IPayService;
import com.ocm.pay.service.IShopPayinfoService;
import com.ocm.pay.service.IUserPayinfoService;
import com.ocm.pay.to.OrderPayOkTO;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;

import static com.ocm.pay.constant.AdminPayInfoConstant.*;

/**
 * @Author hqy
 * @Date 11/01/2022
 * @Description
 */
@Service
public class PayServiceImpl implements IPayService {


	@Resource
	private IShopPayinfoService shopPayinfoService;

	@Resource
	private IUserPayinfoService userPayinfoService;

	@Resource
	private IPayListService payListService;

	@Resource
	private RabbitTemplate rabbitTemplate;

	/**
	 * 充值操作
	 * @return
	 */
	@Override
	public boolean recharge(@NotNull Long payeeId,@NotNull String payeeName,@NotNull int payeeType,
							@NotNull BigDecimal amount,
							Long orderId,String orderDescribe,String payPassword,
							Long cardId,@NotNull String bankType,Long bankCard,String cardType,
							String remark){

		//生成账单
		payListService.save(new PayList(ADMIN_PAY_ID,ADMIN_PAY_TYPE,ADMIN_PAY_NAME,payeeId,payeeType,payeeName,amount,bankCard,bankType,cardId,cardType,remark, ExchangeTypeConstant.EXCHANGE_TYPE_RECHARGE,orderId,orderDescribe));
		/*
		 * 付款账号为用户
		 */
		if(payeeType== PayTypeConstant.PAY_TYPE_USER){
			UserPayinfo payer = userPayinfoService.getOne(new QueryWrapper<UserPayinfo>().eq("user_id", payeeId).eq("is_deleted", 0));
			if(!payPassword.equals(payer.getPayPassword()))
				throw new ServiceException(ResultCode.PAY_PASSWORD_ERROR);

			//付款账户加款

			return userPayinfoService.update(new UpdateWrapper<UserPayinfo>()
				.eq("user_id",payeeId)
				.eq("is_deleted",0)
				.setSql("balance=balance+"+amount));
			/*
			 * 付款账号为店家
			 */
		}else if(payeeType== PayTypeConstant.PAY_TYPE_SHOP){
			ShopPayinfo payer = shopPayinfoService.getOne(new QueryWrapper<ShopPayinfo>().eq("shop_id", payeeId).eq("is_deleted", 0));
			if(!payPassword.equals(payer.getPayPassword())){
				throw new ServiceException(ResultCode.PAY_PASSWORD_ERROR);
			}
			//付款账户加款

			return shopPayinfoService.update(new UpdateWrapper<ShopPayinfo>()
				.eq("shop_id",payeeId)
				.eq("is_deleted",0)
				.setSql("balance=balance+"+amount));
		}
		throw new ServiceException("未知账户类型");

	}
	/**
	 * 提现操作
	 */
	@Override
	@Transactional
	public boolean withdraw(@NotNull Long payerId,@NotNull String payerName,int payerType,
							@NotNull BigDecimal amount,
							@NotNull Long cardId,@NotNull String bankType,@NotNull Long bankCard,@NotNull String cardType,
							String payPassword, String remark){
		//生成账单(todo 银行卡主键已传入 可以在此扩展)
		payListService.save(new PayList(payerId,payerType,payerName,ADMIN_PAY_ID,ADMIN_PAY_TYPE,ADMIN_PAY_NAME,amount,bankCard,bankType,cardId,cardType,remark, ExchangeTypeConstant.EXCHANGE_TYPE_WITHDRAW,null,null));
		/*
		 * 付款账号为用户
		 */
		if(payerType== PayTypeConstant.PAY_TYPE_USER){
			UserPayinfo payer = userPayinfoService.getOne(new QueryWrapper<UserPayinfo>().eq("user_id", payerId).eq("is_deleted", 0));
			if(!payPassword.equals(payer.getPayPassword()))
				throw new ServiceException(ResultCode.PAY_PASSWORD_ERROR);

			//付款账户扣款
			if(payer.getBalance().compareTo(amount)<0)
				throw new ServiceException(ResultCode.PAY_BALANCE_NOT_ALLOWED);

			//todo 加入提现队列
			return userPayinfoService.update(new UpdateWrapper<UserPayinfo>()
				.eq("user_id",payerId)
				.eq("is_deleted",0)
				.ge("balance",amount)
				.setSql("balance=balance-"+amount));
		/*
		 * 付款账号为店家
		 */
		}else if(payerType== PayTypeConstant.PAY_TYPE_SHOP){
			ShopPayinfo payer = shopPayinfoService.getOne(new QueryWrapper<ShopPayinfo>().eq("shop_id", payerId).eq("is_deleted", 0));
			if(!payPassword.equals(payer.getPayPassword())){
				throw new ServiceException(ResultCode.PAY_PASSWORD_ERROR);
			}
			//付款账户扣款
			if(payer.getBalance().compareTo(amount)<0)
				throw new ServiceException(ResultCode.PAY_BALANCE_NOT_ALLOWED);

			//todo 加入提现队列
			return shopPayinfoService.update(new UpdateWrapper<ShopPayinfo>()
				.eq("shop_id",payerId)
				.eq("is_deleted",0)
				.ge("balance",amount)
				.setSql("balance=balance-"+amount));
		}
		throw new ServiceException("未知账户类型");

	}

	/**
	 * 退款-订单退款操作
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void refund(@Nullable BigDecimal amount,
						  @NotNull Long orderId,
							String remark){
		PayList payList = payListService.getOne(new QueryWrapper<PayList>().eq("order_id", orderId).eq("status",1));
		PayList p = new PayList();
		if(amount==null){
			amount=payList.getAmount();
		}
		if(payList==null||payList.getAmount()==null){
			throw new ServiceException("此退款操作异常,未找到有效账单!");
		}

		if(payList.getAmount().compareTo(amount)<0){
			throw new ServiceException("此退款金额异常,请检查操作");
		}

		payList.setStatus(0);
		p.setRefund(amount);
		p.setId(payList.getId());
		p.setStatus(0);

		//更新账单状态
		payListService.updateById(p);
		Long payeeId = payList.getPayeeId();
		Integer payeeType = payList.getPayeeType();

		Long payerId = payList.getPayerId();
		Integer payerType = payList.getPayerType();

		//原收款账号扣款
		if(payeeType== PayTypeConstant.PAY_TYPE_SHOP){

			//商家账户扣款-冻结余额扣款
			if(!shopPayinfoService.update(new UpdateWrapper<ShopPayinfo>()
				.eq("shop_id",payeeId)
				.eq("is_deleted",0)
				.ge("freeze",amount)
				.setSql("freeze=freeze-"+amount))){
				throw new ServiceException("商家扣款异常,退款异常");
			}
			//商家账户加款-得到交易-退款金额
			if(payList.getAmount().compareTo(payList.getRefund())>-1)
				if(!shopPayinfoService.update(new UpdateWrapper<ShopPayinfo>()
				.eq("shop_id",payeeId)
				.eq("is_deleted",0)
				.setSql("balance=balance+"+payList.getAmount().subtract(amount)))){
				throw new ServiceException("商家加款异常,退款异常");
			}
		}

		//原付款账号收款
		if(payerType== PayTypeConstant.PAY_TYPE_USER){
			//用户账户加款
			if(!userPayinfoService.update(new UpdateWrapper<UserPayinfo>()
				.eq("user_id",payerId)
				.eq("is_deleted",0)
				.setSql("balance=balance+"+amount))){
				throw new ServiceException("用户加款异常,退款异常");
			}
		}
	}


	/**
	 * 进行交易-购买商品
	 */
	@Override
	@Transactional
	public boolean deal(@NotNull Long payerId,@NotNull String payerName,@NotNull int payerType,
				 @NotNull Long payeeId,@NotNull String payeeName,@NotNull int payeeType,
				 @NotNull BigDecimal amount,
				 Long orderId,String orderDescribe,
				 Long cardId,@NotNull String bankType,Long bankCard,String cardType,
				 String payPassword, String remark){

		//生成账单
		payListService.save(new PayList(payerId,payerType,payerName,payeeId,payeeType,payeeName,amount,bankCard,bankType,cardId,cardType,remark, ExchangeTypeConstant.EXCHANGE_TYPE_DEAL,orderId,orderDescribe));
		/*
		 * 付款账号为用户
		 */
		if(payerType== PayTypeConstant.PAY_TYPE_USER){
			UserPayinfo payer = userPayinfoService.getOne(new QueryWrapper<UserPayinfo>().eq("user_id", payerId).eq("is_deleted", 0));
			if(!payPassword.equals(payer.getPayPassword()))
				throw new ServiceException(ResultCode.PAY_PASSWORD_ERROR);

			//付款账户扣款
			if(payer.getBalance().compareTo(amount)<0)
				throw new ServiceException(ResultCode.PAY_BALANCE_NOT_ALLOWED);

			if(!userPayinfoService.update(new UpdateWrapper<UserPayinfo>()
				.eq("user_id",payerId)
				.eq("is_deleted",0)
				.ge("balance",amount)
				.setSql("balance=balance-"+amount))){
				throw new ServiceException("用户扣款异常,支付异常");
//			}
//
//			if(payeeType==PAY_TYPE_USER){
//				UserPayinfo payee = userPayinfoService.getOne(new QueryWrapper<UserPayinfo>().eq("user_id", payerId).eq("is_deleted", 0));
//				//用户账户加款
//				return userPayinfoService.update(new UpdateWrapper<UserPayinfo>()
//					.eq("user_id",payee)
//					.eq("is_deleted",0)
//					.setSql("balance=balance+"+amount));
//

			}else if(payeeType== PayTypeConstant.PAY_TYPE_SHOP){
				//商家账户加款-至冻结余额中
				if(!shopPayinfoService.update(new UpdateWrapper<ShopPayinfo>()
						.eq("shop_id",payeeId)
						.eq("is_deleted",0)
						.setSql("freeze=freeze+"+amount))){
					throw new ServiceException("商家加款异常,支付异常");
				}
				//消息队列 通知订单支付成功
				rabbitTemplate.convertAndSend("order-event-exchange","order.pay.order",new OrderPayOkTO(orderId,bankType,bankCard));

				return true;

			}else if(payeeType== PayTypeConstant.PAY_TYPE_ADMIN){
				return true;
			}

		/*
		 * 付款账号为店家
 		 */
//		}else if(payerType==PAY_TYPE_SHOP){
//			ShopPayinfo payer = shopPayinfoService.getOne(new QueryWrapper<ShopPayinfo>().eq("shop_id", payeeId).eq("is_deleted", 0));
//			if(!payPassword.equals(payer.getPayPassword())){
//				throw new ServiceException(ResultCode.PAY_PASSWORD_ERROR);
//			}
//			//付款账户扣款
//			if(payer.getBalance().compareTo(amount)<0)
//				throw new ServiceException(ResultCode.PAY_BALANCE_NOT_ALLOWED);
//
//			shopPayinfoService.update(new UpdateWrapper<ShopPayinfo>()
//				.eq("shop_id",payerId)
//				.eq("is_deleted",0)
//				.set("balance",payer.getBalance().subtract(amount)));
//			if(payeeType==PAY_TYPE_USER){
//				UserPayinfo payee = userPayinfoService.getOne(new QueryWrapper<UserPayinfo>().eq("user_id", payerId).eq("is_deleted", 0));
//				//用户账户加款-至余额中
//				return userPayinfoService.update(new UpdateWrapper<UserPayinfo>()
//					.eq("user_id",payee)
//					.eq("is_deleted",0)
//					.set("balance",payee.getBalance().add(amount)));
//			}else if(payeeType==PAY_TYPE_SHOP){
//				ShopPayinfo payee = shopPayinfoService.getOne(new QueryWrapper<ShopPayinfo>().eq("shop_id", payerId).eq("is_deleted", 0));
//				//商家账户加款-至余额中
//				return userPayinfoService.update(new UpdateWrapper<UserPayinfo>()
//					.eq("shop_id",payee)
//					.eq("is_deleted",0)
//					.set("balance",payee.getBalance().add(amount)));
//			}else if(payeeType==PAY_TYPE_ADMIN){
//				return true;
//			}
//
//		/*
//		 * 付款账户类型为admin
//		 */
//		}else if(payerType==PAY_TYPE_ADMIN){
//
//			if(payeeType==PAY_TYPE_USER){
//				UserPayinfo payee = userPayinfoService.getOne(new QueryWrapper<UserPayinfo>().eq("user_id", payerId).eq("is_deleted", 0));
//				//用户账户加款
//				return userPayinfoService.update(new UpdateWrapper<UserPayinfo>()
//					.eq("user_id",payee)
//					.eq("is_deleted",0)
//					.set("balance",payee.getBalance().add(amount)));
//			}else if(payeeType==PAY_TYPE_SHOP){
//				ShopPayinfo payee = shopPayinfoService.getOne(new QueryWrapper<ShopPayinfo>().eq("shop_id", payerId).eq("is_deleted", 0));
//				//商家账户加款-至余额中
//				return userPayinfoService.update(new UpdateWrapper<UserPayinfo>()
//					.eq("shop_id",payee)
//					.eq("is_deleted",0)
//					.set("balance",payee.getBalance().add(amount)));
//			}
		}
		throw new ServiceException("支付失败，未识别的账户类型");


	}

	/**
	 * 收货操作
	 * @param orderId
	 */
	@Override
	@Transactional
	public void receiving(Long orderId) {

		PayList paylist = payListService.getOne(new QueryWrapper<PayList>().eq("order_id", orderId).eq("status",1));


		if(paylist==null){
			throw new ServiceException("收货失败,找不到有效的支付信息");
		}
		if(!shopPayinfoService.update(new UpdateWrapper<ShopPayinfo>()
			.eq("shop_id",paylist.getPayeeId())
			.setSql("balance=balance+"+paylist.getAmount())
			.setSql("freeze=freeze-"+paylist.getAmount())
			.ge("freeze",paylist.getAmount()))){

			throw new ServiceException("收货失败");

		}
		payListService.update(new UpdateWrapper<PayList>().eq("id",paylist.getId()).set("status",3));


	}
}
